package jdly.water.api.dao.common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

import org.springframework.stereotype.Repository;

import jdly.water.api.model.PageModel;
import jdly.water.api.util.PageUtil;
import jodd.util.StringUtil;

/**
 * @author 坚持到底gl
 * @create 2017-09-26 10:36
 * @desc
 **/
@Repository
public class BaseDAOimpl<T, ID extends Serializable> implements BaseDAO<T, ID> {
	
	public final String FIELD_CREATETIME = "createtime";

	@PersistenceContext
	private EntityManager entityManager;

	@Transactional
	@Override
	public boolean save(T entity) {
		boolean flag = false;
		try {
			entityManager.persist(entity);
			flag = true;
		} catch (Exception e) {
			throw e;
		}
		return flag;
	}

	@Transactional
	@Override
	public Object findByid(Object o, Serializable id) {
		return entityManager.find(o.getClass(), id);
	}

	@Transactional
	@Override
	public List<T> findBysql(String tablename, String filed, Object o) {
		String sql = "from " + tablename + " u WHERE u." + filed + "=?";
		Query query = entityManager.createQuery(sql);
		query.setParameter(1, o);
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@Override
	public Object findObjiectBysql(String tablename, String filed, Object o) {
		String sql = "from " + tablename + " u WHERE u." + filed + "=?";
		Query query = entityManager.createQuery(sql);
		query.setParameter(1, o);

		entityManager.close();
		return query.getSingleResult();
	}

	@Transactional
	@Override
	public List<T> findByMoreFiled(String tablename, LinkedHashMap<String, Object> map) {
		String sql = "from " + tablename + " u WHERE ";
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		List<Object> filedlist = new ArrayList<>();
		for (String filed : list) {
			sql += "u." + filed + "=? and ";
			filedlist.add(filed);
		}
		sql = sql.substring(0, sql.length() - 4);
		Query query = entityManager.createQuery(sql);
		for (int i = 0; i < filedlist.size(); i++) {
			query.setParameter(i + 1, map.get(filedlist.get(i)));
		}
		List<T> listRe = query.getResultList();
		entityManager.close();
		return listRe;
	}

	@Override
	public List<T> findByMoreFiledpages(String tablename, LinkedHashMap<String, Object> map, int start, int pageNumber,
			Map<String, String> sortmap) {
		StringBuffer sql = new StringBuffer("from " + tablename + " u WHERE 1 = 1 ");
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		List<Object> filedlist = new ArrayList<>();
		int pindex = 0;
		for (String filed : list) {
			
			if(map.get(filed)!=null&&StringUtil.isNotEmpty(map.get(filed).toString())) {
				String content = map.get(filed).toString();
				if(content.contains("*")) {
					sql.append(" AND u.").append(filed).append(" like ?  ");
				}else {
					sql.append(" AND u.").append(filed).append("= ?  ");
				}
				
				filedlist.add(filed);
			}
		}
		// 获取排序内容
		if (sortmap==null||sortmap.isEmpty()) {
			sortmap = new HashMap<String, String>();
			sortmap.put("createtime", "DESC");
		}
		sortmap.put("id", "DESC");
		Set<String> keylist = sortmap.keySet();
		sql.append(" ORDER BY ");
		for (String s : keylist) {
			sql.append(s).append(" ").append(sortmap.get(s)).append(",");
		}
		sql.delete(sql.length()-1, sql.length());
		Query query = entityManager.createQuery(sql.toString());
		for (int i = 0; i < filedlist.size(); i++) {
			String content = map.get(filedlist.get(i)).toString();
			if(content.contains("*")) {
				content = content.replace("*", "%");
				query.setParameter(i + 1, content);
			}else {
//				if(map.get(filedlist.get(i)) instanceof Date) {
//					query.setParameter(i + 1, (Date)map.get(filedlist.get(i)),TemporalType.DATE);
//				}else {
					query.setParameter(i + 1, map.get(filedlist.get(i)));
//				}
				
			}
			
		}
		query.setFirstResult((start - 1) * pageNumber);
		query.setMaxResults(pageNumber);
		List<T> listRe = query.getResultList();
		entityManager.close();
		return listRe;
	}
	
	@Override
	public List<T> findByMoreFiledpages(String tablename, LinkedHashMap<String, Object> map, int start, int pageNumber,
			Map<String, String> sortmap,Map<String,Object> beginmap,Map<String,Object> endmap) {
		StringBuffer sql = new StringBuffer("from " + tablename + " u WHERE 1 = 1 ");
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		List<Object> filedlist = new ArrayList<>();
		int pindex = 0;
		for (String filed : list) {
			
			if(map.get(filed)!=null&&StringUtil.isNotEmpty(map.get(filed).toString())) {
				String content = map.get(filed).toString();
				if(content.contains("*")) {
					sql.append(" AND u.").append(filed).append(" like ?  ");
				}else {
					sql.append(" AND u.").append(filed).append("= ?  ");
				}
				
				filedlist.add(filed);
			}
		}
		if(beginmap!=null&&!beginmap.isEmpty()) {
			Set<String> kset = beginmap.keySet();
			for(String k:kset) {
				if(beginmap.get(k)!=null&&StringUtil.isNotEmpty(beginmap.get(k).toString())) {
					sql.append(" AND u."+k).append(" >= ? ");
					filedlist.add("p"+pindex);
					map.put("p"+pindex, beginmap.get(k));
					pindex++;
				}
			}
			sql.delete(sql.length()-1, sql.length());
		}
		if(endmap!=null&&!endmap.isEmpty()) {
			Set<String> kset = endmap.keySet();
			for(String k:kset) {
				if(endmap.get(k)!=null) {
					sql.append(" AND u."+k).append(" <= ? ");
					filedlist.add("p"+pindex);
					map.put("p"+pindex, endmap.get(k));
					pindex++;
				}
			}
			sql.delete(sql.length()-1, sql.length());
		}
		// 获取排序内容
		if (sortmap==null||sortmap.isEmpty()) {
			sortmap = new HashMap<String, String>();
			sortmap.put("createtime", "DESC");
		}
		Set<String> keylist = sortmap.keySet();
		sql.append(" ORDER BY ");
		for (String s : keylist) {
			sql.append(s).append(" ").append(sortmap.get(s)).append(",");
		}
		sql.delete(sql.length()-1, sql.length());
		Query query = entityManager.createQuery(sql.toString());
		for (int i = 0; i < filedlist.size(); i++) {
			String content = map.get(filedlist.get(i)).toString();
			if(content.contains("*")) {
				content = content.replace("*", "%");
				query.setParameter(i + 1, content);
			}else {
//				if(map.get(filedlist.get(i)) instanceof Date) {
//					query.setParameter(i + 1, (Date)map.get(filedlist.get(i)),TemporalType.DATE);
//				}else {
					query.setParameter(i + 1, map.get(filedlist.get(i)));
//				}
				
			}
			
		}
		query.setFirstResult((start - 1) * pageNumber);
		query.setMaxResults(pageNumber);
		List<T> listRe = query.getResultList();
		entityManager.close();
		return listRe;
	}
	
	@Override
	public List<T> findByMoreFiledpages(String tablename, LinkedHashMap<String, Object> map, PageModel page) {
		StringBuilder sql = new StringBuilder("from ").append(tablename).append(" u WHERE 1 = 1 ");
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		List<Object> filedlist = new ArrayList<>();
		int pindex = 0;
		for (String filed : list) {
			
			if(map.get(filed)!=null&&StringUtil.isNotEmpty(map.get(filed).toString())) {
				String content = map.get(filed).toString();
				if(content.contains("*")) {
					sql.append(" AND u.").append(filed).append(" like ?  ");
				}else {
					sql.append(" AND u.").append(filed).append("= ?  ");
				}
				
				filedlist.add(filed);
			}
		}
		sql.append(" ORDER BY ");
		// 获取排序内容
		if (StringUtil.isEmpty(page.getSortname())) {
			
			sql.append(PageUtil.DEFAULT_SORT_FIELD).append(" ").append(PageUtil.DEFAULT_SORT_TYPE).append(",");
		}else {
			sql.append(page.getSortname()).append(" ").append(page.getOrdertype()).append(",");
		}
		
		sql.delete(sql.length()-1, sql.length());
		Query query = entityManager.createQuery(sql.toString());
		for (int i = 0; i < filedlist.size(); i++) {
			String content = map.get(filedlist.get(i)).toString();
			if(content.contains("*")) {
				content = content.replace("*", "%");
				query.setParameter(i + 1, content);
			}else {
//				if(map.get(filedlist.get(i)) instanceof Date) {
//					query.setParameter(i + 1, (Date)map.get(filedlist.get(i)),TemporalType.DATE);
//				}else {
					query.setParameter(i + 1, map.get(filedlist.get(i)));
//				}
				
			}
			
		}
		query.setFirstResult((page.getPage() - 1) * page.getLimit());
		query.setMaxResults(page.getLimit());
		List<T> listRe = query.getResultList();
		entityManager.close();
		return listRe;
	}

	@Transactional
	@Override
	public List<T> findpages(String tablename, String filed, Object o, int start, int pageNumer) {
		String sql = "from " + tablename + " u WHERE u." + filed + "=?";
		System.out.println(sql + "--------page--sql语句-------------");
		List<T> list = new ArrayList<>();
		try {
			Query query = entityManager.createQuery(sql);
			query.setParameter(1, o);
			query.setFirstResult((start - 1) * pageNumer);
			query.setMaxResults(pageNumer);
			list = query.getResultList();
			entityManager.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return list;
	}

	@Transactional
	@Override
	public boolean update(T entity) {
		boolean flag = false;
		try {
			entityManager.merge(entity);
			flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	@Transactional
	@Override
	public Integer updateMoreFiled(String tablename, LinkedHashMap<String, Object> map) {
		String sql = "UPDATE " + tablename + " AS u SET ";
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		for (int i = 0; i < list.size() - 1; i++) {
			if (map.get(list.get(i)).getClass().getTypeName() == "java.lang.String") {
				sql += "u." + list.get(i) + "='" + map.get(list.get(i)) + "' , ";
			} else {
				sql += "u." + list.get(i) + "=" + map.get(list.get(i)) + " , ";
			}
		}
		sql = sql.substring(0, sql.length() - 2);
		sql += "where u.id=? ";
		int resurlt = 0;
		try {
			Query query = entityManager.createQuery(sql);
			query.setParameter(1, map.get("id"));
			resurlt = query.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();

		}
		return resurlt;
	}

	@Transactional
	@Override
	public boolean delete(T entity) {
		boolean flag = false;
		try {
			entityManager.remove(entityManager.merge(entity));
			flag = true;
		} catch (Exception e) {
			System.out.println("---------------删除出错---------------");
		}
		return flag;
	}

	@Override
	public Object findCount(String tablename, LinkedHashMap<String, Object> map) {
		String sql = "select count(u) from " + tablename + " u WHERE ";
		Set<String> set = null;
		set = map.keySet();
		List<String> list = new ArrayList<>(set);
		List<Object> filedlist = new ArrayList<>();
		for (String filed : list) {
			sql += "u." + filed + "=? and ";
			filedlist.add(filed);
		}
		sql = sql.substring(0, sql.length() - 4);
		Query query = entityManager.createQuery(sql);
		for (int i = 0; i < filedlist.size(); i++) {
			query.setParameter(i + 1, map.get(filedlist.get(i)));
		}
		return query.getSingleResult();
	}
}